#!/usr/bin/env ruby

require 'mysql2'

tokens = %w(
ADD
AFTER
ALTER
BEGIN
BIT
CHANGE
COLLATE
COLUMN
CREATE
DATABASE
ENGINE
EXISTS
FIRST
IGNORE
IF
LIKE
MEDIUMINT
MODIFY
ONLINE
OFFLINE
SCHEMA
SMALLINT
TABLE
TINYINT
TEMPORARY

UNSIGNED
SIGNED

ZEROFILL
BIT
TINYINT
CHARACTER
SET
COLLATE
SMALLINT
MEDIUMINT
INT
INTEGER
BIGINT
REAL
DOUBLE
PRECISION
FLOAT
DECIMAL
NUMERIC
DATE
TIME
TIMESTAMP
DATETIME
YEAR
FIXED
INT1
INT2
INT3
INT4
INT8
FLOAT4
FLOAT8
MIDDLEINT

CHAR
VARCHAR
NCHAR
NVARCHAR
NATIONAL
VARYING

ASCII
BINARY
VARBINARY
TINYBLOB
BLOB
MEDIUMBLOB
LONGBLOB
TINYTEXT
TEXT
MEDIUMTEXT
LONGTEXT
ENUM
SET
JSON

NOT
NULL
SRID
DEFAULT
CURRENT_TIMESTAMP

AUTO_INCREMENT
UNIQUE
PRIMARY
KEY
COMMENT
COLUMN_FORMAT
FIXED
DYNAMIC
DEFAULT
STORAGE
DISK
MEMORY

CONSTRAINT
WITH
PARSER
KEY_BLOCK_SIZE
USING
BTREE
HASH
INDEX
KEY
FULLTEXT
SPATIAL
FOREIGN
ASC
DESC

DROP

DISABLE
ENABLE
KEYS

RENAME
TO
AS

ORDER
BY

CONVERT
CHARSET

AVG_ROW_LENGTH
CHECKSUM
CONNECTION
DATA
DIRECTORY
INSERT_METHOD
NO
FIRST
LAST
DELAY_KEY_WRITE
MAX_ROWS
MIN_ROWS
PACK_KEYS
PASSWORD
DEFAULT
DYNAMIC
FIXED
COMPRESSED
REDUNDANT
COMPACT
TABLESPACE
STORAGE
DISK
MEMORY
ENCRYPTION

ROW_FORMAT
UNION

RESTRICT
CASCADE

REFERENCES
MATCH
FULL
PARTIAL
SIMPLE
ON
DELETE
UPDATE
RESTRICT
CASCADE
SET
NULL
NO
ACTION

BOOL
BOOLEAN
TRUE
FALSE

ALGORITHM
COPY
INPLACE
INSTANT

VISIBLE
INVISIBLE

LOCK
EXCLUSIVE
NONE
SHARED

VIEW
OR
REPLACE
UNDEFINED
MERGE
TEMPTABLE
DEFINER
CURRENT_USER
SQL
SECURITY
INVOKER

UPGRADE
NAME

NOW
LONG

STATS_AUTO_RECALC
STATS_PERSISTENT
STATS_SAMPLE_PAGES

FORCE
BYTE
UNICODE
CHECK

GEOMETRY
POINT
GEOMETRYCOLLECTION
LINESTRING
MULTILINESTRING
MULTIPOINT
MULTIPOLYGON
POLYGON

SERIAL

PARTITION
PARTITIONS
SUBPARTITION
SUBPARTITIONS
LINEAR
RANGE
COLUMNS
LIST

DISCARD
IMPORT
COALESCE
REORGANIZE
INTO
ANALYZE
OPTIMIZE
REBUILD
REPAIR
REMOVE
PARTITIONING
TRUNCATE
EXCHANGE
WITHOUT
VALIDATION

VIRTUAL
STORED
GENERATED
ALWAYS

LOCALTIME
LOCALTIMESTAMP
CAST

START
TRANSACTION
)


tokens = tokens.select { |t| !t.empty? }.sort.uniq

$connection = Mysql2::Client.new(:database => 'test', :default_file => ENV["HOME"] + '/.my.cnf', :default_group => 'mysql')

def discover_token_availability(tokens, sql)
  tokens.select do |token|
    begin
      $connection.query(sql % token)
      true
    rescue Mysql2::Error => e
      e.message !~ /You have an error in your SQL syntax/
    end
  end
end

$connection.query("CREATE TABLE if not exists column_test ( id int(11) )")
tokens_allowed_in_names = discover_token_availability(tokens, "ALTER TABLE column_test add column %s int(11)")


File.open(File.dirname(__FILE__) + "/mysql_literal_tokens.g4", "w+") do |f|
  f.puts("// This file is automatically generated by src/main/antlr4/imports/generate_tokens.rb")
  f.puts("grammar mysql_literal_tokens;")
  f.puts
  f.puts("tokens_available_for_names: (%s);" % tokens_allowed_in_names.join(" | "))
  f.puts("all_tokens: (%s);" % tokens.sort.uniq.join(" | "))
  f.puts

  tokens.select { |t| !t.empty? }.sort.uniq.each do |t|
    token_value = t.split(//).map do |c|
      if c =~ /[a-zA-Z]/
        c
      else  # underscores and numbers
        "'#{c}'"
      end
    end.join(' ')
    f.puts "%s: %s;" % [t, token_value]
  end

  ('A'..'Z').map do |letter|
    f.puts("fragment %s: [%s%s];" % [letter, letter, letter.downcase]);
  end
end
